#include <map>


/// COURSE
template <class CID>
class Course_t
{
public:
	Course_t(const CID& id) : m_id(id) { }
	
	virtual ~Course_t() {}
	
	virtual void setCourseID(const CID& id) {
		m_id = id;
	}
	
	virtual const CID& getCourseID() const {
		return m_id;
	}
	
private:
	CID m_id;
};


/// FACULTY
template <class FID, class CID>
class Faculty_t
{
public:
	Faculty_t(const FID& id) : m_id(id) { }
	
	virtual ~Faculty_t() {}
	
	virtual void setFacultyID(const FID& id) {
		m_id = id;
	}
	
	virtual const FID& getFacultyID() const {
		return m_id;
	}
	
	virtual bool addCourse(Course_t<CID>* const course) {
		if(getCourse(course->getCourseID()) != NULL)
			return false;
			
		m_courses.insert(std::make_pair(course->getCourseID(), course));
		return true;
	}
	
	virtual Course_t<CID>* getCourse(const CID& id) const {
		CourseContainer::const_iterator it = m_courses.find(id);
		if(it == m_courses.end())
			return NULL;
		
		return it->second;
	}
	
private:
	FID m_id;
	
	typedef map<CID, Course_t<CID>*> CourseContainer;
	CourseContainer m_courses;
};


/// UNIVERSITY
template <class UID, class FID, class CID>
class University_t
{
public:
	University_t(const UID& id) : m_id(id) { }
	
	virtual ~University_t() {}
	
	virtual void setUniversityID(const UID& id) {
		m_id = id;
	}
	
	virtual const UID& getUniversityID() const {
		return m_id;
	}
	
	virtual bool addFaculty(Faculty_t<FID,CID>* const faculty) {
		if(getFaculty(faculty->getFacultyID()) != NULL)
			return false;
			
		m_faculties.insert(std::make_pair(faculty->getFacultyID(), faculty));
		return true;
	}
	
	virtual Faculty_t<FID,CID>* getFaculty(const FID& id) const {
		FacultyContainer::const_iterator it = m_faculties.find(id);
		if(it == m_faculties.end())
			return NULL;
		
		return it->second;
	}
	
private:
	UID m_id;
	
	typedef map<FID, Faculty_t<FID,CID>*> FacultyContainer;
	FacultyContainer m_faculties;
};



void main()
{
	Course_t<int> c1(17);
}